package hc.j2me.item;

import hc.core.ConfigManager;
import hc.core.HCTimer;
import hc.core.IConstant;
import hc.core.util.HCURLUtil;
import hc.j2me.J2MEURLAction;
import hc.j2me.ScreenClientManager;
import hc.j2me.Starter;
import hc.j2me.util.ImageUtility;
import hc.j2me.util.Jcip;

import java.io.IOException;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;

public class CanvasMenu extends GameCanvas {
	private static Image selectBoxImg;
	String[] urls = null;
    short ncol = 0, nrow = 0;
    final int width,height;
    short deltax,deltay;
    int focusX, focusY;
    //虚拟屏的全高，可能含隐藏元素
    int height_vcanvas;
    int shift_y;
    final int size;
    Sprite SP_selectBox;
    
    //每个方格的高(含文字标注)、宽
    private short item_w, item_h;  
    private short title_h;
    //对于非60最小图格的整数倍的行宽，采用居中方式，即左右两端向中缩进，border_x是左缩进量
    private final int border_x;  
    final int dragPixelBorder;
    
    final private LayerManager lm;
    
    private boolean isDragged = false;
    private int pointDragStartX = -1, pointDragStartY = -1;
    
    public CanvasMenu(){
    	this(Jcip.getInstance().getString(),
    			Jcip.getInstance().getArrImage(), Jcip.getInstance().getArrString(), 
    			Jcip.getInstance().getArrString(), (short)Jcip.getInstance().getInt(), 
    			(short)Jcip.getInstance().getInt(), Jcip.getInstance().getBool(), 
    			(short)Jcip.getInstance().getInt()
    			);
    }
    
	/**
     * 
     * @param title
     * @param icons
     * @param iconLabels
     * @param urls
     * @param nrow 无意义，不再使用
     * @param ncol 指定列数；如果为0，则表示系统侦测图片大小及画面尺寸来自动排列
     * @param fullMode
     * @param size
     */
	public CanvasMenu(final String title,
			final Image icons[], final String iconLabels[], final String[] urls, 
			short nrow, short ncol, 
			final boolean fullMode, final short size) {        
        super(false);
        
        setFullScreenMode(true);
    	
        final int BACKGROUD_COLOR = 0x807039;

    	final Font defaultFont = ImageUtility.UI_Font;
    	
//    	不显示Title，如果设置此值，即使是FullScreenMode，也会出现系统Title
//        if(title != null && title.trim().length() > 0){
//        	this.setTitle(title);
//        }
        this.urls = urls;
        this.ncol = ncol;
        this.size = size;
        
        width = ScreenClientManager.getClientWidth();
        height = ScreenClientManager.getClientHeight();
        
        final int _16 = Starter.getIconSize(width, height);
        dragPixelBorder = (short)((_16 == 16)?3:6);
        if(ncol == 0){
        	//自动侦测列数
        	for (int i = 0; i < icons.length; i++) {
				Image image = icons[i];
				if(image.getWidth() > item_w){
					item_w = (short)image.getWidth();
				}
				if(image.getHeight() > item_h){
					item_h = (short)image.getHeight();
				}
			}
        	final int MIN_BOX = 60;
        	if(item_w < MIN_BOX){
        		item_w = MIN_BOX;
        	}
        	if(item_h < MIN_BOX){
        		item_h = MIN_BOX;
        	}
        	ncol = (short)(width / item_w);
        	this.ncol = ncol;
        	
        	item_h = (short)(item_h + ImageUtility.FontHeight + 2);
        }else{
            final int end_x = width - ((short)(width / ncol)) * ncol;
            item_w = (short)((width - end_x) / ncol);
            
            item_h = (short)(item_w + ImageUtility.FontHeight + 2);
        }
        
        border_x = (width - (item_w * ncol)) / 2;
		Image TitleImage = null;
		try {
			TitleImage = Image.createImage("/hc/j2me/res/left_bd.png");
		}catch (Exception e) {
			
		}
        title_h = (short)(TitleImage.getHeight());
        
        this.nrow = (short)(size / this.ncol + (((size%this.ncol)==0)?0:1));
        nrow = this.nrow;
        height_vcanvas = (short)(this.nrow * item_h + title_h);
        if(height_vcanvas > height){
        }else{
        	height_vcanvas = (short)height;
        }
        
        lm = new LayerManager();
        
		try {
			if(selectBoxImg == null){
				selectBoxImg = Image.createImage("/hc/j2me/res/select_60.png");
			}
			SP_selectBox = new Sprite(selectBoxImg);
			lm.append(SP_selectBox);
		} catch (IOException e1) {
		}

        Image screen = Image.createImage(width, height_vcanvas);
		ConfigManager.put(ConfigManager.ANTI_ALIAS, IConstant.TRUE);
        Graphics graphics = screen.getGraphics();
        ConfigManager.put(ConfigManager.ANTI_ALIAS, IConstant.FALSE);
        Sprite screenSprite = new Sprite(screen);
		lm.append(screenSprite);

        {
    		graphics.setColor(BACKGROUD_COLOR);
    		graphics.fillRect(0,0, width, height_vcanvas);
        	{
        		//标题栏
        		try{
					graphics.drawImage(TitleImage, 0, 0, Graphics.LEFT | Graphics.TOP);
					
					TitleImage = Image.createImage("/hc/j2me/res/right_bd.png");
					graphics.drawImage(TitleImage, width, 0, Graphics.RIGHT | Graphics.TOP);
					
					final int left_bd_width = TitleImage.getWidth();
					
					TitleImage = Image.createImage("/hc/j2me/res/title.png");
					for (int i = left_bd_width, end = width / 2 + TitleImage.getWidth(); i < end; ) {
						graphics.drawImage(TitleImage, i, 0, Graphics.LEFT | Graphics.TOP);	
						i += TitleImage.getWidth();
					}
					for (int i = width - left_bd_width, end = width / 2 - TitleImage.getWidth(); i > end; ) {
						graphics.drawImage(TitleImage, i, 0, Graphics.LEFT | Graphics.TOP);	
						i -= TitleImage.getWidth();
					}
				} catch (IOException e) {
				}
        		
        		graphics.setColor(0x00FFCC);
        		Font blod_title = Font.getFont(defaultFont.getFace(), Font.STYLE_BOLD, defaultFont.getSize());
        		if(blod_title == null){
        			blod_title = defaultFont;
        		}
        		graphics.setFont(blod_title);
        		graphics.drawString(title, width / 2, (TitleImage.getHeight() - blod_title.getHeight()) / 2 - 1, 
        				Graphics.HCENTER | Graphics.TOP);
        		
        		graphics.setFont(defaultFont);
        	}
        	
	        boolean isInitPain = false;
	        for(short r = 0; r<this.nrow && !isInitPain; r++){
	            for(short c = 0; c<this.ncol && !isInitPain; c++){
		            try{
		                int idx = r*this.ncol+c;
		                if(idx == size){
		                	isInitPain = true;
		                }else{
		                	repainItem(graphics, c, r, iconLabels, icons, defaultFont);
		                }
		            }catch(Exception e){
		                e.printStackTrace();
		            }
		        }
	        }
            notifySeletedItem(focusX, focusY);
        }
        
        new HCTimer("", 300, true) {
			public void doBiz() {
				refreshScreen();
				remove(this);
			}
		};
    }
	
	private void repainItem(Graphics graphics, short focusX, short focusY, String[] iconLabels, 
			Image[] icons, Font font){
		int topx = focusX * item_w + border_x;
		int topY = focusY * item_h + title_h;
		
//		graphics.setColor(backColor);
//		graphics.drawRoundRect(topx, topY + 1, item_w - 2, item_w - 2, 10, 10);
		
		int idx = focusY * ncol + focusX;
		
		Image image = icons[idx];
		String name = iconLabels[idx];
		
		int centerX = topx + item_w/2;
		int centerY = topY + (item_h - ImageUtility.FontHeight - 1) / 2;
		graphics.drawImage(image, centerX, centerY, Graphics.VCENTER|Graphics.HCENTER);
		String txt = findFitString(name, item_w, font);
		
		ImageUtility.setColor(graphics, ImageUtility.YELLOW);
		graphics.drawString(txt, centerX, topY + item_w + 1, Graphics.TOP|Graphics.HCENTER);
	}
	
	private void shiftOnlyY(final int pixelNum){
		shift_y += pixelNum;
	}
	
	private String findFitString(String text, int maxWidth, Font font){
		String cutText = text;
		while(font.stringWidth(cutText) > maxWidth){
			text = text.substring(0, text.length() - 1);
			cutText = text + "..";
		}
		return cutText;
	}
	
	private void repainSelectedItem(int focusX, int focusY){
		int topx = focusX * item_w + border_x;
		int topY = focusY * item_h;

		SP_selectBox.setPosition(topx, topY + title_h);
	}
	
	/**
	 * 从一个相邻(上下、左右)网格移动到另一个
	 * @param focusX 当前网格坐标
	 * @param focusY
	 * @param oldx -1表示从无开始移到网格
	 * @param oldY 上次网格坐标
	 */
	public void notifySeletedItem(int focusX, int focusY){
		repainSelectedItem(focusX, focusY);
		
        //刷新
        refreshScreen();
	}
	
    private void refreshScreen() {
	    final Graphics lmg = getGraphics();
	    if(lmg != null){
//	    	lm.setViewWindow(0, shift_y, width, height);
	    	lm.paint(lmg, 0, shift_y * (-1));
	    	flushGraphics();
	    }
    }
    
    protected void sizeChanged(int w, int h){
    	
    }

    protected void keyPressed(int keycode) {
		final int gameAction = getGameAction(keycode);
        if (gameAction == LEFT || keycode == KEY_NUM4){
        	if(focusX == 0){
        		if((focusY * ncol + focusX + 1) == size){
        			Starter.soundFail();
        			return;
        		}else{
        			if((focusY * ncol + ncol) <= size){
        				focusX = (ncol - 1);
        			}else{
        				focusX = (size - focusY * ncol - 1);
        			}
        		}
        	}else{
        		focusX--;
        	}
        }else if (gameAction == RIGHT || keycode == KEY_NUM6){
        	focusX++;
        	if(focusX == ncol){
        		focusX = 0;
        	}else{
        		if((focusY * ncol + focusX) == size){
        			focusX = 0;
        		}
        	}
        }else if (gameAction == UP || keycode == KEY_NUM2){ 
        	if(focusY == 0){
        		Starter.soundFail();
        		return;
        	}else{
        		focusY--;
        		final int _shiftNum = focusY * item_h + title_h - shift_y;
				if(_shiftNum < 0){
        			shiftOnlyY(_shiftNum);
        		}
        	}
        }else if (gameAction == DOWN || keycode == KEY_NUM8){
        	final int borderNum = (focusY + 1) * ncol;
    		if(borderNum >= size){
    			Starter.soundFail();
    			return;
    		}else{
    			focusY++;
    			final int _shiftNum = (focusY + 1) * item_h + title_h - shift_y - height;
    			if(_shiftNum > 0){
    				shiftOnlyY(_shiftNum);
    			}
    			
    			if((focusY * ncol + focusX) >= size){
    				focusX = (size % ncol) - 1;
    			}
    		}
        }else if (gameAction == FIRE || keycode == KEY_NUM5){
        	int idx = focusY * ncol + focusX;
        	String url = urls[idx];
        	
        	HCURLUtil.process(url, J2MEURLAction.defaultJ2MEURLActon);
        	return;
        }  

    	notifySeletedItem(focusX, focusY);

    	Starter.soundOK();
    }
    
    private void actionPointDrag(int startX, int startY, int endX, int endY) {
    	shift_y -= (endY - startY);
    	
    	if(shift_y + height > height_vcanvas){
    		shift_y = (height_vcanvas - height);
    	}else if(shift_y < 0){
    		shift_y = 0;
    	}
    	pointDragStartX = endX;
    	pointDragStartY = endY;
    	refreshScreen();
    }

    public void pointerDragged(int x, int y){
		if (pointDragStartX >= (x-dragPixelBorder) && pointDragStartX <= (x+dragPixelBorder) 
				&& pointDragStartY >= (y-dragPixelBorder)&& pointDragStartY <= (y+dragPixelBorder)) {
		}else{
			isDragged = true;
			actionPointDrag(pointDragStartX, pointDragStartY, x, y);
		}
    }
    
    public void pointerPressed(final int x, final int y) {
		pointDragStartX = x;
		pointDragStartY = y;
    }
    
    protected void pointerReleased(int x, int y){
		if(isDragged){
			isDragged = false;
			//忽略细微移动。
			return;
		}

    	final int firstColX = x - border_x;
    	if(firstColX < 0){
    		//左缩进边
    		return;
    	}
		int fx = (firstColX / item_w);
    	if(fx >= ncol){
    		//右缩进边
    		return;
    	}
    	
    	int fy = ((y + shift_y - title_h) / item_h);
    	if((fy * ncol + fx) >= size){
    		return;
    	}
    	
    	focusX = fx;
    	focusY = fy;
    	
    	notifySeletedItem(focusX, focusY);
    	
    	keyPressed(KEY_NUM5);
    }

}